package cn.stylefeng.guns.sys.config;

import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.consts.SpringSecurityConstant;
import cn.stylefeng.guns.sys.core.filter.security.CaptchaValidateFilter;
import cn.stylefeng.guns.sys.core.filter.security.JwtAuthenticationTokenFilter;
import cn.stylefeng.guns.sys.core.filter.security.entrypoint.JwtAuthenticationEntryPoint;
import cn.stylefeng.guns.sys.modular.auth.service.impl.AuthServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class SecurityConfigration {

    @Resource
    private AuthServiceImpl authService;

    @Resource
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    private CaptchaValidateFilter captchaValidateFilter;

    @Resource
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Autowired
    private Environment env;

    /**
     * 开启跨域访问拦截器
     *
     * @author stylefeng
     * @date 2020/4/29 9:50
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        String allowOrigin = env.getProperty("allow-origin");
        if(StrUtil.isEmpty(allowOrigin)){
            allowOrigin="*";
        }
        corsConfiguration.addAllowedOrigin(allowOrigin);
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(source);
    }
    @Bean
    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception{
        //开启模拟请求，比如API POST测试工具的测试，不开启时，API POST为报403错误
//        Customizer.withDefaults();
//        httpSecurity.csrf(csrf -> csrf.disable());
//        httpSecurity.csrf().disable();
        httpSecurity.csrf(AbstractHttpConfigurer::disable);

        //开启跨域访问
//        httpSecurity.cors();
        httpSecurity.cors(httpSecurityCorsConfigurer -> corsFilter());

        //不使用默认退出，自定义退出
//        httpSecurity.logout().disable();
        httpSecurity.logout(AbstractHttpConfigurer::disable);


        //未授权时访问须授权的资源端点
//        httpSecurity.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);
        httpSecurity
                // sample exception handling customization
                .exceptionHandling((exceptionHandling) ->
                        exceptionHandling
                                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                );

        //放开一些接口的权限校验
        for (String notAuthResource : SpringSecurityConstant.NONE_SECURITY_URL_PATTERNS) {
            httpSecurity.authorizeRequests().requestMatchers(new AntPathRequestMatcher(notAuthResource) ).permitAll();
        }

        //其余的都需授权访问
        httpSecurity.authorizeRequests().anyRequest().authenticated();

        //图片验证码过滤器
        httpSecurity.addFilterBefore(captchaValidateFilter, UsernamePasswordAuthenticationFilter.class);

        //前置token过滤器
        httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //用户详情service
        httpSecurity.userDetailsService(authService);

        //全局不创建session
//        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        httpSecurity.sessionManagement(withDefaults());

        //禁用页面缓存，返回的都是json
        httpSecurity
                .headers((headers) ->
                        headers
                                .contentTypeOptions(withDefaults())
                                .xssProtection(withDefaults())
                                .cacheControl(withDefaults())
                                .httpStrictTransportSecurity(withDefaults())
                                // 禁用iframe嵌入网页
                                .frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)
//                                .frameOptions(withDefaults())
                );
        return httpSecurity.build();
    }
}
